/**
 * #### 单例模式
 * @author zhentiw
 * @see https://www.cnblogs.com/Answer1215/p/18750571
 * @param classCtor 类构造函数
 * @returns 代理对象
 */
export function singleton<T extends new (...args: any[]) => object>(
  classCtor: T
): T {
  // 声明一个变量，用于存储实例
  let instance!: InstanceType<T>;

  // 创建一个代理对象
  const proxy = new Proxy(classCtor, {
    // 当代理对象被构造时，执行以下操作
    construct(target, args, newTarget) {
      // 如果实例不存在，则创建实例
      if (!instance) {
        instance = Reflect.construct(
          target,
          args,
          newTarget
        ) as InstanceType<T>;
      }
      // 返回实例
      return instance;
    },
  });

  // 将代理对象的构造函数指向代理对象
  classCtor.prototype.constructor = proxy;

  // 返回代理对象
  return proxy as T;
}
